package com.cloudcc.implementationTools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudcc.ccTool.*;

import java.util.*;
/***source_begin***/


/**
 * Author t.han
 * Date 2024-10-30 11:41
 * Project Quectel-CRM
 * Description //TODO
 */
public class saveLayout {
    public CCService cs;
    public UserInfo userInfo;
    public DevLogger devLogger;
    public String classLogName;
    public String Url = "https://ap10.apis.cloudcc.cn";

    public saveLayout(UserInfo userInfo) {
        this.userInfo = userInfo;
        cs = new CCService(userInfo);
        devLogger = new DevLogger(userInfo);
        classLogName = this.getClass().getSimpleName();
    }

    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo();
        saveLayout ta = new saveLayout(userInfo);

//        ta.Execute();
        ta.relatedListExecute();



    }


    /**
     * 执行称动相关列表方法
     * 该方法遍历所有对象的映射，对每个对象执行关联列表的查询并打印结果
     */
    public void relatedListExecute() {
        // 获取所有对象的映射
        Map<String, String> tableMap = allObject();

        // 如果映射不为空，则遍历映射中的每个键值对
        if (!tableMap.isEmpty()) {
            for (String key : tableMap.keySet()) {
                // 获取当前键对应的值，并转换为字符串
                String value = StringUtil.str(tableMap.get(key));
                // 初始化消息字符串
                String msg = "";
                // 打印当前键和值
                System.out.println("Key: " + key + ", Value: " + value);
                // 如果值不为空，则查询关联列表
                if (!"".equals(value)) {
                    msg = queryTableRelatedList(value);
                } else {
                    // 如果值为空，则设置消息为“未查询ID”
                    msg = "未查询ID";
                }

                // 打印查询结果或消息
                System.out.println("==== " + msg);
            }
        }
    }

    public String queryTableRelatedList(String objid) {
        String msg = "";
        String retStr = "";
        List<String> rList = new ArrayList<>();
        //  OBJ_ID ='2024CE26C81BB99Ao41Q' ---  测试对象 ID
        // 只查询移动布局
        String sql = "select id,parentid,name from tp_sys_layout where OBJ_ID ='" + objid + "' AND parentid is not null";
        List<CCObject> dataList = cs.cqlQuery("tp_sys_layout", sql);
        if (dataList != null && dataList.size() > 0) {
            for (CCObject ac : dataList) {
                String layid = StringUtil.str(ac.get("id"));//页面布局id - 移动布局id
                String parentid = StringUtil.str(ac.get("parentid"));//关联pc布局id
                String layoutname = StringUtil.str(ac.get("name"));//布局名称

                //拼装移动布局参数
                JSONObject parObj = addMobileRelatedListParameters(objid, parentid, layid);
                if (parObj != null && !parObj.isEmpty()) {
                    retStr = parObj.toJSONString();
                    msg = saveRelatedList(retStr);
                } else {
                    msg = "未获取到相关列表字段！";
                }

                String msg2 = "11111PC布局ID：" + parentid + "，布局名称：" + layoutname + "，" + msg;
                rList.add(msg2);
            }
        }
        System.out.println(sql);
        return rList.toString();
    }

    /**
     * 生成移动设备相关列表参数
     * 该方法用于准备和格式化移动设备上相关列表的配置参数
     *
     * @param objid 对象ID，用于标识特定的对象
     * @param layoutid 布局ID，用于标识PC端的布局
     * @param MobileLayoutid 移动布局ID，用于标识移动设备上的布局
     * @return 返回包含移动设备相关列表配置的JSONObject
     */
    public JSONObject addMobileRelatedListParameters(String objid, String layoutid, String MobileLayoutid) {
        JSONObject parObj = new JSONObject();

        // 创建一个空的JSONArray，用于存储相关列表的配置
        JSONArray relatedLists = new JSONArray();

        // 转换PC端布局到移动设备布局，获取移动设备上相关列表的配置
        JSONArray relatedListArray = pcToMobileRelatedList(layoutid, MobileLayoutid);
        if (relatedListArray != null && !relatedListArray.isEmpty()) {

            // 查询与布局关联的相关列表信息
            Map<String, Object> relatedListMap = queryRelatedListByLayout(objid, layoutid);
            if (relatedListMap != null && !relatedListMap.isEmpty()) {

                // 遍历移动设备上的相关列表配置
                for (int i = 0; i < relatedListArray.size(); i++) {
                    JSONObject obj1 = relatedListArray.getJSONObject(i);
                    String pcid = StringUtil.str(obj1.getString("pcid"));

                    // 获取当前相关列表的配置
                    JSONObject onrelList = (JSONObject) relatedListMap.get(pcid);
                    System.out.println("objid==="+objid);
                    // 提取排序字段和排序顺序
                    String sortColumn = StringUtil.str(onrelList.get("sortColumn"));// 排序字段
                    boolean sortDesc = StringUtil.str2b(onrelList.get("sortDesc")); //排序顺序
                    // 处理列表按钮的撤销状态
                    JSONObject butjson = onrelList.getJSONObject("stdListButtonsRevoked"); //删除按钮JSON
                    JSONObject stdListButtonsRevoked = new JSONObject();
                    if (butjson != null && !butjson.isEmpty()) {
                        if (butjson.containsKey("adc2024913D41E7sBuDV")) {
                            stdListButtonsRevoked.put("adc2024913D41E7sBuDV", true);
                        }
                    }
                    // 准备自定义字段排序列表
                    List<String> customizedColumns = new ArrayList<>(); //字段排序
                    //
                    JSONArray selectableColumns = onrelList.getJSONArray("selectableColumns");
                    if (selectableColumns != null && !selectableColumns.isEmpty()) {
                        for (int j = 0; j < selectableColumns.size(); j++) {
                            JSONObject selectableColumn = selectableColumns.getJSONObject(j);
                            String filterColumn = StringUtil.str(selectableColumn.get("filterColumn"));
                            customizedColumns.add(filterColumn);
                        }
                    }

                    // 创建一个新的JSONObject，用于存储当前相关列表的配置
                    JSONObject listObj = new JSONObject();
                    String mobid = StringUtil.str(obj1.get("mobid"));
                    if (!"".equals(mobid)) {
                        listObj.put("id", obj1.getString("mobid"));
                        listObj.put("seq", obj1.getString("seq"));
                        listObj.put("customListButtonsAdded", new JSONArray());
                        listObj.put("sortColumn", sortColumn);
                        listObj.put("sortDesc", sortDesc);
                        listObj.put("stdListButtonsRevoked", stdListButtonsRevoked);
                        listObj.put("customizedColumns", customizedColumns);

                        // 将当前相关列表的配置添加到relatedLists中
                        relatedLists.add(listObj);
                    }

                }
            }
        }
        // 创建一个新的JSONObject，用于存储所有相关列表的配置
        JSONObject listObj = new JSONObject();
        if (relatedLists != null && !relatedLists.isEmpty()) {
            listObj.put("relatedLists", relatedLists);
        }

        // 如果listObj不为空，则将其作为参数的一部分添加到parObj中
        if (listObj != null && !listObj.isEmpty()) {
            parObj.put("layoutId", layoutid);
            parObj.put("type", "mobile");
            parObj.put("layoutJson", listObj.toString());
        }

        // 返回包含所有配置参数的JSONObject
        return parObj;
    }

    /**
     * 根据布局查询相关列表
     * 该方法通过发送HTTP POST请求，查询与特定对象和布局相关的列表信息，并将结果以Map形式返回
     *
     * @param objid    对象ID，用于指定查询的对象
     * @param layoutid 布局ID，用于指定查询的布局
     * @return 返回一个Map，其中键是相关列表的ID，值是包含列表信息的JSONObject
     */
    public Map queryRelatedListByLayout(String objid, String layoutid) {
        // 初始化一个Map，用于存储相关列表的信息
        Map<String, Object> pcRelatedListMap = new HashMap<>();
        // 定义CRM系统的API URL，用于查询布局相关的列表信息
        String Purl = Url+"/ccsetup/api/modifyLayoutLightning/queryRelatedListByLayout";

        // 创建一个空的JSON对象，用于封装请求参数
        JSONObject parObj = new JSONObject();
        // 将对象ID和布局ID放入请求参数中
        parObj.put("objId", objid);
        parObj.put("layoutId", layoutid);

        // 发送POST请求并获取响应
        String ObjStr = cs.CCPost(Purl, parObj.toString());
        // 解析响应字符串为JSON对象
        JSONObject obj = JSONObject.parseObject(ObjStr);

        // 检查响应结果是否成功
        if (StringUtil.str2b(obj.getString("result"))) {
            // 获取响应数据中的对象
            JSONObject dataObj = obj.getJSONObject("data");
            // 获取布局数据数组
            JSONArray listdata = dataObj.getJSONArray("layoutData");

            // 遍历布局数据数组，处理每一个布局数据项
            for (int i = 0; i < listdata.size(); i++) {
                // 获取当前布局数据项中的相关列表数组
                JSONArray relatedLists = listdata.getJSONObject(i).getJSONArray("relatedLists");
                // 遍历相关列表数组，处理每一个相关列表项
                for (int j = 0; j < relatedLists.size(); j++) {
                    // 获取当前相关列表项的JSON对象
                    JSONObject relatedList_json = relatedLists.getJSONObject(j);
                    // 获取相关列表项的ID
                    String id = relatedList_json.getString("id");
                    // 将相关列表的ID和其信息存入Map中
                    pcRelatedListMap.put(id, relatedList_json);
                }
            }
        }
        // 返回存储了相关列表信息的Map
//        System.out.println("queryRelatedListByLayout = " + pcRelatedListMap);
        return pcRelatedListMap;
    }


    /**
     * 将PC端布局的相关列表转换为移动端布局的相关列表
     *
     * @param pclayoutid     PC端布局ID，用于查询PC端的相关列表
     * @param mobilelayoutid 移动端布局ID，用于查询移动端的相关列表
     * @return 返回一个JSONArray对象，包含从PC端布局相关列表转换而来的移动端布局相关列表
     */
    public JSONArray pcToMobileRelatedList(String pclayoutid, String mobilelayoutid) {
        // 初始化移动端相关列表的JSONArray
        JSONArray mobileArry = new JSONArray();

        //查询PC端布局相关列表
        String pcsql = "SELECT * FROM tp_sys_relatedlist where layout_id='" + pclayoutid + "' and is_show='1' order by seq";
        List<CCObject> pcList = cs.cqlQuery("tp_sys_relatedlist", pcsql);

        if (pcList != null && pcList.size() > 0) {
            //查询移动端布局相关列表
            String mobsql = "SELECT * FROM tp_sys_relatedlist where layout_id='" + mobilelayoutid + "'";
            List<CCObject> moblist = cs.cqlQuery("tp_sys_relatedlist", mobsql);

            //使用Map存储移动端布局相关列表，以便快速查找
            Map<String, String> mobMap = new HashMap<>();
            if (moblist != null && moblist.size() > 0) {
                System.out.println("moblist = " + moblist);
                for (CCObject mobac : moblist) {
                    String listtype = StringUtil.str(mobac.get("relatedlist_type"));
                    String field_id = StringUtil.str(mobac.get("field_id"));
                    String id = StringUtil.str(mobac.get("id"));
                    if ("custom".equals(listtype)) {
                        mobMap.put(field_id, id);
                    } else {
                        mobMap.put(listtype, id);
                    }
                }
            }

            //判断移动端布局相关列表是否为空
            if (!mobMap.isEmpty()) {
                for (CCObject ac : pcList) {
                    JSONObject mobJson = new JSONObject();
                    String listtype = StringUtil.str(ac.get("relatedlist_type"));
                    String field_id = StringUtil.str(ac.get("field_id"));
                    String seq = StringUtil.str(ac.get("seq"));
                    String pcid = StringUtil.str(ac.get("id"));
                    mobJson.put("pcid", pcid);
                    if ("custom".equals(listtype)) {
                        mobJson.put("mobid", mobMap.get(field_id));
                    } else {
                        mobJson.put("mobid", mobMap.get(listtype));
                    }
                    mobJson.put("seq", seq);
                    mobileArry.add(mobJson);
                }
            }
        }
        //返回移动端布局相关列表的JSONArray
        System.out.println("pcToMobileRelatedList = " + mobileArry);
        return mobileArry;
    }


/**
 * 保存移动布局相关列表的信息
 * 该方法通过发送HTTP POST请求来保存相关列表的信息，并根据响应结果判断操作是否成功
 *
 * @param parStr 包含要保存的相关列表信息的字符串
 * @return 返回一个字符串，表示操作结果
 */
public String saveRelatedList(String parStr) {
    // 初始化错误消息为空字符串
    String errmsg = "";

    // 定义布局相关列表保存的API URL
    String purl = Url+"/ccsetup/api/modifyLayoutLightning/saveRelatedList";

    // 发送POST请求并获取响应
    String ObjStr = cs.CCPost(purl, parStr);
    // 打印响应结果，便于调试
//    System.out.println("ObjStr = " + ObjStr);

    // 解析响应的JSON对象
    JSONObject obj = JSONObject.parseObject(ObjStr);

    // 根据响应结果判断操作是否成功
    if (StringUtil.str2b(obj.getString("result"))) {
//            System.out.println("操作成功！");
        errmsg = "操作成功！";
    } else {
        // 获取并打印失败原因
        String returnInfo = StringUtil.str(obj.getString("returnInfo"));
//            System.out.println("操作失败-returnInfo = " + returnInfo);
        errmsg = "操作失败！" + returnInfo;
    }
    // 返回操作结果
    return errmsg;
}



    // todo 移动布局执行方法
    public void Execute() {
        Map<String, String> tableMap = allObject();

        if (!tableMap.isEmpty()) {
            for (String key : tableMap.keySet()) {
                String value = StringUtil.str(tableMap.get(key));
                String msg = "";
                if (!"".equals(value)) {
                    msg = queryTableLayout(value);
                } else {
                    msg = "未查询ID";
                }

                System.out.println("Key: " + key + ", Value: " + value + " ==== " + msg);
            }
        }
    }

    /**
     * TODO 生成对象ID的移动布局
     * 该方法主要负责查询指定对象ID的移动布局信息，并根据查询结果进行处理
     *
     * @param objid 对象ID，用于查询表布局
     * @return 返回处理结果的字符串表示
     */
    public String queryTableLayout(String objid) {
        // 初始化消息字符串，用于存储处理过程中的消息
        String msg = "";
        // 初始化返回字符串，用于存储最终的返回结果
        String retStr = "";
        // 初始化列表，用于存储处理结果
        List<String> rList = new ArrayList<>();
        //  OBJ_ID ='2024CE26C81BB99Ao41Q' ---  测试对象 ID
        // 只查询移动布局
        // 构造SQL查询语句，查询移动布局的相关信息
        String sql = "select id,parentid,name from tp_sys_layout where OBJ_ID ='" + objid + "' AND parentid is not null";
        // 执行查询，获取布局数据列表
        List<CCObject> dataList = cs.cqlQuery("tp_sys_layout", sql);
        // 检查查询结果是否非空且不为空列表
        if (dataList != null && dataList.size() > 0) {
            // 遍历查询结果，处理每个布局对象
            for (CCObject ac : dataList) {
                // 提取布局ID、父布局ID和布局名称
                String layid = StringUtil.str(ac.get("id"));//页面布局id - 移动布局id
                String parentid = StringUtil.str(ac.get("parentid"));//关联pc布局id
                String layoutname = StringUtil.str(ac.get("name"));//布局名称

                // 拼装移动布局参数
                // 调用方法，为移动布局添加参数，并转换为JSON字符串
                JSONObject parObj = addMobileLayoutParameters(objid, parentid, layid);
                retStr = parObj.toJSONString();
                // 检查返回的JSON字符串是否非空
                if (!"".equals(retStr)) {
                    // 如果非空，调用保存布局的方法，并存储结果消息
                    msg = savelayout(retStr);

                } else {
                    // 如果为空，设置消息表示未获取到页面布局字段
                    msg = "未获取到页面布局字段！";
                }
                // 构造包含PC布局ID、布局名称和处理消息的字符串，并添加到结果列表中
                String msg2 = "2222PC布局ID：" + parentid + "，布局名称：" + layoutname + "，" + msg;
                rList.add(msg2);
            }
        }
        // 返回结果列表的字符串表示
        return rList.toString();
    }


    /**
     * 添加移动端布局参数
     * <p>
     * 该方法用于构建和返回一个包含移动端布局参数的JSONObject
     * 它通过调用API获取布局信息，然后根据获取的数据构造一个新的布局JSON对象
     *
     * @param objid          对象ID，用于指定布局的对象
     * @param layoutid       布局ID，用于指定需要修改的布局
     * @param MobileLayoutid 移动端布局ID，用于在移动端上应用的特定布局
     * @return 返回一个包含移动端布局参数的JSONObject
     */
    public JSONObject addMobileLayoutParameters(String objid, String layoutid, String MobileLayoutid) {
        //返回 布局参数
        JSONObject layObj = new JSONObject();

        // API URL和参数构建
        String Purl = Url+"/ccsetup/api/modifyLayoutLightning/queryLayout";
        JSONObject parObj = new JSONObject();
        parObj.put("objId", objid);
        parObj.put("layoutId", layoutid);

        // 发送请求并解析响应
        String ObjStr = cs.CCPost(Purl, parObj.toString());
        JSONObject obj = JSONObject.parseObject(ObjStr);

        // 检查响应结果
        if (StringUtil.str2b(obj.getString("result"))) {
            JSONObject dataObj = obj.getJSONObject("data");
            JSONArray sections = dataObj.getJSONArray("sections");

            // 处理sections数据
            if (sections != null && !sections.isEmpty()) {
                List<String> layColumns = new ArrayList<>();
                for (int i = 0; i < sections.size(); i++) {
                    JSONObject section = sections.getJSONObject(i);
                    String sectionid = section.getString("sectionId");
                    String sectionname = section.getString("sectionName");

                    // 直接获取 JSONArray
                    JSONArray columns = section.getJSONArray("columns");
                    // 将 JSONArray 转换为 List<String>
                    List<String> list1 = columns.toJavaList(String.class);

                    if (list1 != null && list1.size() > 0) {
                        for (String value : list1) {
                            List<String> filedList = JSON.parseArray(value).toJavaList(String.class);
                            if (filedList != null && filedList.size() > 0) {
                                for (String fstr : filedList) {
                                    layColumns.add(fstr);
                                }
                            }
                        }
                    }
                }

                // 构建新的布局JSON对象
                if (layColumns != null && layColumns.size() > 0) {
                    String secSql = "select id,name,LAYOUT_ID from tp_sys_layout_section where LAYOUT_ID='" + MobileLayoutid + "' and seq='1'";
                    List<CCObject> dseclist = cs.cqlQuery("tp_sys_layout_section", secSql);

                    if (dseclist != null && dseclist.size() > 0) {
                        String mobLayoutName = StringUtil.str(dseclist.get(0).get("name"));
                        String mobLayoutId = StringUtil.str(dseclist.get(0).get("id"));

                        JSONArray layColumnsArry = new JSONArray();
                        layColumnsArry.add(layColumns);

                        JSONArray sectionsArry = new JSONArray();
                        JSONObject sectionsObj = new JSONObject();
                        sectionsObj.put("sectionName", mobLayoutName);
                        sectionsObj.put("showEditHeader", true);
                        sectionsObj.put("columns", layColumnsArry);
                        sectionsObj.put("showDetailHeader", true);
                        sectionsObj.put("sectionId", mobLayoutId);
                        sectionsObj.put("labelKey", mobLayoutName);

                        sectionsArry.add(sectionsObj);

                        JSONObject layoutJson = new JSONObject();
                        layoutJson.put("sections", sectionsArry);

                        layObj.put("layoutId", layoutid);
                        layObj.put("layoutJson", layoutJson.toString());
                        layObj.put("type", "mobile");
                    } else {
                        System.err.println("未找到布局-objId = " + objid + ", layoutId = " + layoutid);
                    }
                }
            }
        }

        return layObj;
    }

    /**
     * 移动保存方法
     * 此方法用于将布局信息保存到CRM系统中它通过调用移动端接口来修改布局
     *
     * @param parStr 包含布局信息的字符串
     */
    public String savelayout(String parStr) {
        String errmsg = "";
        // 移动端 接口URL
        String Purl = Url+"/ccsetup/api/modifyLayoutLightning/saveLayout";

        // 发送POST请求并获取响应
        String ObjStr = cs.CCPost(Purl, parStr);
        // 打印响应结果，便于调试
//    System.out.println("ObjStr = " + ObjStr);
        // 解析响应的JSON对象
        JSONObject obj = JSONObject.parseObject(ObjStr);

        // 根据响应结果判断操作是否成功
        if (StringUtil.str2b(obj.getString("result"))) {
//            System.out.println("操作成功！");
            errmsg = "操作成功！";
        } else {
            // 获取并打印失败原因
            String returnInfo = StringUtil.str(obj.getString("returnInfo"));
//            System.out.println("操作失败-returnInfo = " + returnInfo);
            errmsg = "操作失败！" + returnInfo;
        }
        return errmsg;
    }


    /**
     * 获取所有对象的映射
     * <p>
     * 该方法旨在创建并返回一个包含特定对象名称与其对应ID的映射
     * 它首先定义了一组感兴趣的对象名称，然后通过查询数据库获取这些对象的详细信息，
     * 最终将每个对象的名称与其对应的ID一起存储在映射中并返回
     *
     * @return 包含对象名称与ID映射的Map对象
     */
    public Map allObject() {
        Set<String> data = new HashSet<>();
//                data.add("campaign");
//                data.add("hdfyhxsq_obj");
//        data.add("hdfypjxx_obj");
//        data.add("jsxx_obj");
//        data.add("hdfyhxsqmx_obj");
//        data.add("sysq_obj");
//        data.add("sysqmx_obj");
//        data.add("yjsq_obj");
//        data.add("sqmx_obj");
//        data.add("contractdetails_obj");
//        data.add("contract_obj");
//        data.add("zdyhqk_obj");
//        data.add("fysq_obj");
//        data.add("fysqmx_obj");
//        data.add("thhxjxx_obj");
//        data.add("thhjjxx_obj");
//        data.add("thhsq_obj");
//        data.add("hkjh_obj");
//        data.add("rkjl_obj");
//        data.add("ccrz_obj");
//        data.add("ccgl_obj");qysc
//        data.add("ccjhmx_obj");
        data.add("qysc_obj");


        // 初始化一个映射，用于存储对象名称与ID的对应关系
        Map<String, String> tableMap = new HashMap();
        // 构造查询语句，以获取感兴趣对象的详细信息
        String objsql = "select datatable_name,schemetable_name,prefix,id,label from TP_SYS_OBJECT where schemetable_name in " + StringUtil.set2SqlIn(data) + "";
        // 执行查询并获取结果列表
        List<CCObject> dlist = cs.cqlQuery("TP_SYS_OBJECT", objsql);
        // 如果查询结果不为空，则遍历结果列表，提取并存储对象名称与ID的对应关系
        if (dlist.size() > 0) {
            for (CCObject ac : dlist) {
                String tablename = StringUtil.str(ac.get("schemetable_name"));
                String tableid = StringUtil.str(ac.get("id"));
                // 将对象名称与ID的对应关系存储在映射中
                tableMap.put(tablename, tableid);
            }
        }
        // 返回包含对象名称与ID映射的Map对象
        return tableMap;
    }


}
/***source_end***/